package com.gitee.qdbp.general.mgr.controller.basedata.settings;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import com.alibaba.fastjson.JSON;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.jdbc.ordering.OrderPaging;
import com.gitee.qdbp.able.jdbc.paging.PageList;
import com.gitee.qdbp.able.result.IBatchResult;
import com.gitee.qdbp.able.result.ResponseMessage;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.base.annotation.OperateRecord;
import com.gitee.qdbp.base.enums.OperateType;
import com.gitee.qdbp.base.system.model.IAccount;
import com.gitee.qdbp.base.utils.EnumTools;
import com.gitee.qdbp.base.utils.FileIoTools;
import com.gitee.qdbp.base.utils.SessionTools;
import com.gitee.qdbp.base.utils.WebTools;
import com.gitee.qdbp.general.common.api.settings.model.AreaBean;
import com.gitee.qdbp.general.common.api.settings.model.AreaChangedBean;
import com.gitee.qdbp.general.common.api.settings.model.AreaChangedDetails;
import com.gitee.qdbp.general.common.api.settings.model.AreaDivisionBean;
import com.gitee.qdbp.general.common.api.settings.model.AreaDivisionUpdate;
import com.gitee.qdbp.general.common.api.settings.model.AreaDivisionWhere;
import com.gitee.qdbp.general.common.api.settings.service.IAreaDivisionBatch;
import com.gitee.qdbp.general.common.api.settings.service.IAreaDivisionExecutor;
import com.gitee.qdbp.general.common.api.settings.service.IAreaDivisionQueryer;
import com.gitee.qdbp.general.common.enums.AreaType;
import com.gitee.qdbp.tools.utils.ConvertTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 行政区划基本信息控制器
 *
 * @author zhaohuihua
 * @version 170401
 */
@Controller
@RequestMapping("actions/area-division")
public class AreaDivisionController {

    @Autowired
    private IAreaDivisionQueryer areaDivisionQueryer;
    @Autowired
    private IAreaDivisionExecutor areaDivisionExecutor;
    @Autowired
    private IAreaDivisionBatch areaDivisionBatch;

    /**
     * 查询行政区划列表
     *
     * @param paging 分页信息
     * @param model 查询条件
     * @return 行政区划列表
     */
    @ResponseBody
    @RequestMapping("list")
    @OperateRecord(value = "行政区划:查询", type = OperateType.QUERY)
    public ResponseMessage list(AreaDivisionWhere model, OrderPaging paging, Boolean extra) {
        if (VerifyTools.isBlank(model.getSceneType())) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + model.getSceneType() + ":query");

        try {
            PageList<AreaDivisionBean> list = areaDivisionQueryer.list(model, paging);
            ResponseMessage result = new ResponseMessage(list);
            if (Boolean.TRUE.equals(extra)) {
                result.addExtra(EnumTools.getEnumsResource(AreaType.class));
            }
            return result;
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 创建行政区划 **/
    @ResponseBody
    @RequestMapping("create")
    @OperateRecord(value = "行政区划:创建", type = OperateType.CREATE)
    public ResponseMessage create(String sceneType, AreaBean model) {
        if (VerifyTools.isBlank(sceneType)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + sceneType + ":create");

        try {
            IAccount operator = SessionTools.getLoginUser();
            areaDivisionExecutor.create(sceneType, model, operator);
            return new ResponseMessage(model);
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 修改行政区划 **/
    @ResponseBody
    @RequestMapping("update")
    @OperateRecord(value = "行政区划:修改", type = OperateType.UPDATE)
    public ResponseMessage update(AreaDivisionUpdate model) {
        if (VerifyTools.isBlank(model.getSceneType())) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + model.getSceneType() + ":update");

        try {
            IAccount operator = SessionTools.getLoginUser();
            areaDivisionExecutor.update(model, operator);
            return new ResponseMessage(model);
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 删除行政区划 **/
    @ResponseBody
    @RequestMapping("delete")
    @OperateRecord(value = "行政区划:删除", type = OperateType.DELETE)
    public ResponseMessage delete(String sceneType, String[] id) {
        if (VerifyTools.isBlank(sceneType)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + sceneType + ":delete");

        try {
            IAccount operator = SessionTools.getLoginUser();
            areaDivisionExecutor.delete(sceneType, ConvertTools.toList(id), operator);
            return new ResponseMessage();
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 导入 **/
    @ResponseBody
    @RequestMapping("import")
    @OperateRecord(value = "行政区划:导入", type = OperateType.CREATE)
    public ResponseMessage imports(String sceneType, @RequestParam("excel") CommonsMultipartFile file) {
        if (VerifyTools.isBlank(sceneType)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + sceneType + ":import");

        try (InputStream is = file.getInputStream()) {
            IAccount operator = SessionTools.getLoginUser();
            IBatchResult result = areaDivisionBatch.imports(sceneType, is, operator);
            return new ResponseMessage(result);
        } catch (IOException e) {
            return new ResponseMessage(e);
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 导出 **/
    @RequestMapping("export.do") // 应该是.do,  一旦报错就跳到一个错误页面,  而不是json格式的报错
    @OperateRecord(value = "行政区划:导出", type = OperateType.QUERY)
    public void exports(AreaDivisionWhere where, OrderPaging paging, String filename, HttpServletRequest request,
            HttpServletResponse response) throws ServiceException, IOException {
        if (VerifyTools.isBlank(where.getSceneType())) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + where.getSceneType() + ":export");

        String root = WebTools.me.getWebRoot();
        // 设置content-disposition响应头控制浏览器以下载的形式打开文件
        response.setHeader("content-disposition", FileIoTools.toAttachmentDesc(request, filename));
        areaDivisionBatch.exports(where, paging, root, response.getOutputStream());
    }

    /** 与互联网上的最新行政区划比对, 返回变动情况 **/
    @ResponseBody
    @RequestMapping("compare")
    @OperateRecord(value = "行政区划:比对", type = OperateType.QUERY)
    public ResponseMessage compare(String sceneType) {
        if (VerifyTools.isBlank(sceneType)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + sceneType + ":sync");

        try {
            IAccount me = SessionTools.getLoginUser();
            List<AreaChangedDetails> list = areaDivisionExecutor.compare(sceneType, me);
            return new ResponseMessage(list);
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 保存比对结果 **/
    @ResponseBody
    @RequestMapping("save-changed")
    @OperateRecord(value = "行政区划:同步", type = OperateType.UPDATE)
    public ResponseMessage compare(String sceneType, String changed) {
        if (VerifyTools.isBlank(sceneType)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(changed)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + sceneType + ":sync");

        List<AreaChangedBean> data = JSON.parseArray(changed, AreaChangedBean.class);
        try {
            IAccount me = SessionTools.getLoginUser();
            areaDivisionExecutor.saveChanged(sceneType, data, me);
            return new ResponseMessage();
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 以互联网上的最新行政区划全量替换掉DB中的数据 **/
    @ResponseBody
    @RequestMapping("sync-data")
    @OperateRecord(value = "行政区划:同步", type = OperateType.UPDATE)
    public ResponseMessage syncData(String sceneType) {
        if (VerifyTools.isBlank(sceneType)) {
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        SecurityUtils.getSubject().isPermitted("resource:" + sceneType + ":sync");

        try {
            IAccount me = SessionTools.getLoginUser();
            areaDivisionExecutor.syncData(sceneType, me);
            return new ResponseMessage();
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }
}
